home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Atari Mega Archive 1
/
Atari Mega Archive - Volume 1.iso
/
mint
/
utils
/
lack.zoo
/
trap2.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-01-01
|
16KB
|
592 lines
#include "lack.h"
#include "sysvars.h"
#include "xbra.h"
#include <string.h>
#include <osbind.h>
#include <mintbind.h>
lap *lapps[NUM_APPS];
lap *curapp;
struct save_area
{
int in_use;
long dregs[8]; /* These are gem's registers at the time of the
* task switch. User's registers are pushed onto
* the usp. */
void (*stopped)(); /* Where the task switch was called from. */
long aregs[6]; /* a1-a6 as dregs */
void *g_ssp; /* + 0x3e */
void *usp; /* + 0x42 */
void *u_ssp; /* + 0x46 */
};
ki;
int in_aes; /* are we servicing an aes call, rather than letting some apid run */
int get_menu_title; /* let the controler acc's do menu_register? */
int aes_active; /* I don't know how to keep this thing up to date */
int aes_version;
struct save_area *apid0_save=NULL; /* test for wether apid 0 is the desktop, see below */
struct appl *apid0_appl; /* " " " ... */
int is_desk=FALSE;
static int first=TRUE;
int apid; /* the running application, to the best of my knowledge */
int __desk_stk[1024];
const long desk_stk=(long)&__desk_stk[1023];
static void (*yield_aes)(void);
void *os_base;
/*void *os_end; I don't know how to set this */
struct global_action *gl_action;
/* in lack.s: */
extern void trap_2(void);
extern void trap_3(void);
extern void trap_13(void);
extern void _first_leave_aes(void);
extern void _desk_leave_aes(void);
/* in jump.s: */
extern int setjump(lap *);
extern int longjump(lap *);
/* in wind.c: */
extern void desk_zap_windows(void);
/* vectors to search down before unloading acc, the first nine spaces are for
* kbdvecs.
* Maybe I should add mfp ints, or save everything which doesn't have the high
* byte set. It does not take much memory to save these things and refer back
* to them.
* If you add vectors leave off the cast, and the error message will tell you
* what NUM_VECS should be changed to.
*/
#define NUM_VECS 54
char **vecs[NUM_VECS]={(char **)0x0, (char **)0x0, (char **)0x0, (char **)0x0,
(char **)0x0, (char **)0x0, (char **)0x0, (char **)0x0, (char **)0x0,
(char **)0x08, (char **)0x0c, (char **)0x10, (char **)0x14, (char **)0x18,
(char **)0x1c, (char **)0x20, (char **)0x24, (char **)0x2c, (char **)0x34,
(char **)0x38, (char **)0x3c, (char **)0x60, (char **)0x70, (char **)0x84,
(char **)0x88, (char **)0xb4, (char **)0xb8, (char **)0xc0, (char **)0xe0,
(char **)0xe4, (char **)0xe8, (char **)0x114, (char **)0x400, (char **)0x404,
(char **)0x408, (char **)0x42a, (char **)0x472, (char **)0x476, (char **)0x47e,
(char **)0x4f6, (char **)0x506, (char **)0x50a, (char **)0x50e, (char **)0x512,
(char **)0x51e, (char **)0x53e, (char **)0x55e, (char **)0x57e, (char **)0x108,
(char **)0x118, (char **)0x124, (char **)0x128, (char **)0x12c, (char **)0x130};
struct xbra gem= {XBRA_MAGIC, 0x6c61636bL /*'lack'*/, NULL, JMP_OPCODE,
(void *)trap_2};
struct xbra mytrap={XBRA_MAGIC, 0x6c61636bL /*'lack'*/, NULL, JMP_OPCODE,
(void *)trap_3};
struct xbra bios= {XBRA_MAGIC, 0x6c61636bL /*'lack'*/, NULL, JMP_OPCODE,
(void *)trap_13};
install_trap2()
{
long ssp;
int sr;
char *sp;
char **kvecs;
int c;
kvecs=(char **)Kbdvbase(); /* this assumes Kbdbase returns the a pointer
* to the actual vectors */
for(c=0; c<9; c++)
vecs[c]=kvecs++;
ssp=Super(0);
sr=spl7();
os_base=(*_sysbase)->os_beg;
gem.xb_old=*(void **)0x88L;
*(short **)0x88L=&gem.xb_op;
mytrap.xb_old=*(void **)0x8cL;
*(short **)0x8cL=&mytrap.xb_op;
bios.xb_old=*(void **)0xb4L;
*(short **)0xb4L=&bios.xb_op;
/* find apid0_appl */
apid0_appl=aes_appl;
while(apid0_appl->apid!=0 && apid0_appl->next)
apid0_appl=apid0_appl->next;
if(apid0_appl->apid!=0)
{
ALERT("could not find apid 0");
apid0_appl=NULL;
}else{
DEBUG("apid 0 application structure at %lx", apid0_appl);
apid0_save=(struct save_area *)apid0_appl->save_area;
yield_aes=*(((void(**)())apid0_save->g_ssp) - 1);
}
lapps[0]->istk=desk_stk;
if(!strncmp (apid0_appl->name, " ", 8))
{
/* at startup, anything will look like the desktop */
DEBUG("lack: apid 0 is desktop");
is_desk=TRUE;
sp=(char *)apid0_save->g_ssp;
if(*sp==0 || *longframe)
/* if it isn't a 030, it can't have an address with the top
* byte set, so this test for linef works */
{
lapps[0]->pc=*(void(**))sp;
*(void(**))sp=_desk_leave_aes;
aes_version=0x160; /* will be reset by lackcontrol's appl_init */
DEBUG("tos >= 1.6");
}else{
lapps[0]->pc=*(void(**))(sp + 2);
*(void(**))(sp + 2)=_desk_leave_aes;
aes_version=0x140; /* will be reset by lackcontrol's appl_init */
DEBUG("tos < 1.6");
}
}else{
DEBUG("lack: apid 0 is not desktop");
first=TRUE;
sp=(char *)apid0_save->u_ssp;
if(*longframe)
{
lapps[0]->pc=*(void(**))(sp + 4);
*(void (**))(sp + 4)=_first_leave_aes;
}else{
lapps[0]->pc=*(void(**))(sp + 2);
*(void(**))(sp + 2)=_first_leave_aes;
}
lapps[0]->in_aes=1;
}DEBUG("changing pc %lx on stack %lx", lapps[0]->pc, sp);
spl(sr);
Super(ssp);
}
void
get_gem_stack()
{
/* acc user and gem ssp's are on the same stack. The acc needs to
* return from Dcntl(LA_INIT_ACC) while it's gem stack is in use.
* So, we change the gem stack so the acc's ssp can be used for
* Dcntl(LA_WAKE_APP) when it is time to return to the caller pid.
* For the first acc, it needs to call Dcntl(LA_WAKE_APP) when gem
* pid 0 is running, but MiNT lackontrol proccess is active, that
* is, when apid 0 returns from the trap 2 call made by lackontrol.
* I hope this makes some sense.
*/
struct save_area *my_save;
char *my_gem_stack;
long ssp; int sr;
my_gem_stack=(char *)Mxalloc(4096, M_PROT_S | M_ALT);
curapp->mystk_base = curapp->mystk = (long)my_gem_stack+4096;
my_gem_stack+=2048;
ssp=Super(0);
sr=spl7();
my_save=aes_appl->save_area;
DEBUG("changing gem's ssp from %lx to %lx", my_save->g_ssp, my_gem_stack);
my_save->g_ssp=my_gem_stack;
spl(sr);
Super(ssp);
}
int
check_for_desk(int was_desk)
{
char *sp;
if(!strncmp(apid0_appl->name, " ", 8))
{
/* Make sure apid 0 is still the desktop */
sp=(char *)apid0_save->g_ssp;
if(aes_version > 0x140) /* notice that this differs from the rom rev */
{
/* save the pc of desktop and make it return to me, so I can
* adjust the MiNT pid, etc. I figure the desktop call the
* aes function dipatcher via line-f or jsr, (depending on wether
* there is such a thing as line-f).
*/
if (*(void(**))sp!=_desk_leave_aes)
{
lapps[0]->pc=*(void(**))sp;
*(void(**))sp=_desk_leave_aes;
DEBUG("changed pc %lx on stack %lx", lapps[0]->pc, sp);
}
}else{
if(*(void(**))((char *)sp+2)!=_desk_leave_aes)
{
lapps[0]->pc=*(void(**))((char *)sp+2);
*(void(**))((char *)sp+2)=_desk_leave_aes;
DEBUG("changed pc %lx on stack %lx", lapps[0]->pc, sp);
}
}
lapps[0]->in_aes=1;
if (!was_desk) lapps[0]->istk=desk_stk;
}else{
is_desk=FALSE;
if(was_desk) /* desktop has done wind_new */ desk_zap_windows();
else /* an application has exited, but the desktop didn't
* wake up. */
DEBUG("not desktop");
}
}
void
print_global(AESP *call)
{
char line[80];
int last=0;
int count, *global=call->global;
DEBUG("global array from call %d", call->control[0]);
for(count=0; count<15; count++)
{
ksprintf(&line[last], "%x, ", global[count]);
last=strlen(line);
if(last>73)
{
DEBUG(line);
last=0;
}
}
if(last) DEBUG(line);
}
int
unload()
{
/* this is called by handle_action during entry to or exit from aes */
/* we certainly are putting alot of stuff on someone else's stack */
AESP *old=_aesparams;
int (*oldcall)()=__aes__;
NEW_AESP(a);
BASEPAGE *b=curapp->acc->base;
char *start=b->p_tbase;
char *end